package jtwittconsolepackage;

import jTwittConsoleExceptions.IJTwittConsoleErrorTypes;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.TreeMap;

/**
 * Super class for all repositories containing tweets.
 * Stores the tweets in usable way to print them immediately.
 */
public class TweetRepository  implements IJTwittConsoleErrorTypes
{
    public TreeMap<Long, TweetReadyForPrint> storedTweets;
    //used to remember in which refresh run the tweet has been refreshed
    protected int refreshCounter;

    public int getRefreshCounter()
    {
        return refreshCounter;
    }

     protected TweetRepository()
     {
        refreshCounter = 0;
        storedTweets = new TreeMap<Long, TweetReadyForPrint>();
     }

     /**
      * Store a tweet in the repository and mark it as refreshed
      * @param tweet the tweet to store
      */
     public void addTweet(TweetReadyForPrint tweet)
     {
         tweet.setRefreshedInLastRun();

         //warn if an old tweet is added again to the repository
         if(storedTweets.containsKey(tweet.getId()))
         {
            System.out.println("!! Warning tweet has been added again to"
                    + " repository !!");
         }

         storedTweets.put(tweet.getId(), tweet);
     }

     /**
      * If the repository contains the tweet with the given id;
      * @param id
      * @return
      */
     public boolean containsTweet(long id)
     {
         boolean result = true;

         try
         {
                 result = storedTweets.containsKey(id);
         }
         catch(NullPointerException npe)
         {
                 ErrorLogger.getInstance().exceptionOccured("An error occured"
                         + " while looking up tweets",
                         "-1", npe, errorCodeLookUpTweet);

                 result = false;
         }

         return result;
     }

     /**
      * Increases the refresh counter;
      */
     public void increaseRefreshCounter()
     {
         this.refreshCounter++;
     }

     /**
      * Removes old tweets from the repository
      */
     public void cleanUpOldTweets()
     {
         try
         {
             for(Iterator<TweetReadyForPrint> tweetIterator = storedTweets.values().iterator();
                    tweetIterator.hasNext();)
             {
                TweetReadyForPrint tweetReadyForPrint = tweetIterator.next();

                if(tweetReadyForPrint.refreshCounter < this.refreshCounter)
                {
                     tweetIterator.remove();
                }
             }
         }
         catch (ConcurrentModificationException cme)
         {
                ErrorLogger.getInstance().exceptionOccured("An error occured"
                        + " while cleaning up old tweets",
                        "-1", cme, errorCodeCleanUpOldTweets);
        }
     }

     /**
      * Returns the amount of tweets stored in the repository.
      * @return returns the number of stored tweets
      */
     public int getNumberOfStoredTweets()
     {
             return this.storedTweets.size();
     }
}
